using System;
using System.Reflection;

namespace uk.co.tonyditchfield.utility.reflection
{
    public class MethodProperties
    {
        /// <summary>
        /// Gets the calling method from a navigable level of stack frames (method calls) up the stack
        /// possibly evil and expensive, but it works for now!!
        /// </summary>
        /// <param name="type"></param>
        /// <param name="stackFrames"></param>
        /// <returns></returns>
        /// <exception cref="System.ArguementNullException"></exception>
        /// <exception cref="System.TypeLoadException"></exception>
        public Object GetCallingMethodCustomAttribute(Type type, int stackFrames)
        {
            MethodBase mb = new System.Diagnostics.StackFrame(stackFrames).GetMethod();
            return mb.GetCustomAttributes(type, false)[0];
        }

        public Object[] GetCallingMethodCustomAttributes(Type type, int stackFrames)
        {
            MethodBase mb = new System.Diagnostics.StackFrame(stackFrames).GetMethod();
            return mb.GetCustomAttributes(type, false);
        }

        /// <summary>
        /// Gets the calling methods properties dependant on how far up the stack you want to go!!
        /// </summary>
        /// <param name="stackFrames"></param>
        /// <returns></returns>
        public MethodBase GetCallingMethod(int stackFrames)
        {
            return new System.Diagnostics.StackFrame(stackFrames).GetMethod();
        }

        public Type GetCallingType(int stackFrames)
        {
            return new System.Diagnostics.StackFrame(stackFrames).GetMethod().DeclaringType;
        }
    }
}